/* Original Author:  Dominick O'Dierno
 * Date: 2007   odiernod@gmail.com     --Originally intended for use with DOMercury:  http://www.odierno.com/domercury
 * Description: Controls anything to do with Aliases
 * 
 * --CHANGELOG--
 * 
 * */

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Windows.Forms;
using DOMercury.Interfaces;
using DOMercury.Items;


namespace DOMercury.Managers
{
    public static class AliasManager
    {
        private static List<Alias> aliases;
        private static List<IItemContainer> aliasContainers;

#region Public Functions
        //Save
        public static void Save()
        {
            AliasIOManager.WriteAliases(ref aliases);
        }
        //Load
        public static void Load()
        {
            aliases = new List<Alias>();
            aliasContainers = new List<IItemContainer>();
            try
            {
                AliasIOManager.ReadAliases(ref aliases);
                foreach (Alias a in aliases)
                {
                    aliasContainers.Add(IndexManager.NewIItemContainerwPriority(a, false, false));
                }
            }
            catch (FileNotFoundException ex)
            {
                MessageBox.Show("Could Not find \"DOMercuryAliases.xml\". Unable to load aliases.", "Error, Unable to find DOMercuryAliases.xml", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                MessageBox.Show("\"DOMercuryAliases.xml\" is corrupt or damaged, or possibly in an incorrect format. Unable to load aliases.  \nIf DOMercury crashes after this, delete everything inside DOMercuryAliases.xml then restart DOMercury", "Error, Unable to read DOMercuryAliases.xml", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
        }
        //Add
        public static bool Add(string Alias, string Path, string Parameters, string Description)
        {
            if (aliases.Exists(delegate(Alias a) { return a.AliasName == Alias; }))
            {
                return false;
            }
            else
            {
                Alias al = new Alias(Alias, Path, Parameters, Description);
                aliases.Add(al);
                aliasContainers.Add(IndexManager.NewIItemContainerwPriority(al, false, false));
                aliases.Sort();
                aliasContainers.Sort();
                Save();
                return true;
            }
        }
        //Delete
        public static void Delete(Alias Alias)
        {
            IItemContainer aliasToDelete = GetByName(Alias);
            aliasContainers.Remove(aliasToDelete);
            aliases.Remove(Alias);
            Save();
        }

        public static List<Alias> AliasList
        {
            get
            {
                return aliases;
            }
        }

        public static List<IItemContainer> AliasContainers
        {
            get
            {
                return aliasContainers;
            }
        }

        public static Alias GetByName(string name)
        {
            return aliases.Find(delegate(Alias a) { return a.AliasName == name; });
        }

        public static IItemContainer GetByName(Alias alias)
        {
            return aliasContainers.Find(delegate(IItemContainer a) { return a.DisplayName == alias.AliasName; });
        }

        #endregion
    }
    public class AliasIOManager
    {
        public static void ReadAliases(ref List<Alias> AliasList)
        {
            XmlTextReader r = new XmlTextReader(new FileStream(Path.GetDirectoryName(Application.ExecutablePath) + "\\DOMercuryAliases.xml", FileMode.Open, FileAccess.Read));
            while ((!r.EOF) && r.Name.Trim().CompareTo("Aliases") != 0)
            {
                r.Read();
            }
            if (!r.EOF)
            {
                r.Read();
            }
            //r.Read();
            //r.Read();
            while ((!r.EOF) && r.Name.Trim().CompareTo("Aliases") != 0)
            {
                if (r.NodeType == XmlNodeType.EndElement)
                {
                    r.Read();
                }
                else
                {
                    switch (r.Name.Trim())
                    {
                        case "Alias":
                            AliasList.Add(ReadAliases(r)); break;
                        case "":
                            r.Read(); break;
                        default:
                            r.Skip(); break;
                    }
                }
            }
            r.Close();
        }

        private static Alias ReadAliases(XmlTextReader r)
        {
            string a = r.GetAttribute("Alias");
            string p = r.GetAttribute("Path");
            string pe = r.GetAttribute("Parameters");
            string d = r.GetAttribute("Description");
            r.Skip();
            return new Alias(a, p, pe, d);
        }

        public static void WriteAliases(ref List<Alias> AliasList)
        {
            XmlTextWriter w = new XmlTextWriter(new StreamWriter(Path.GetDirectoryName(Application.ExecutablePath) + "\\DOMercuryAliases.xml", false, Encoding.UTF8));
            w.WriteStartElement("Aliases");
            foreach (Alias a in AliasList)
            {
                WriteAliases(w, a);
            }
            w.WriteEndElement();
            w.Flush();
            w.BaseStream.Close();
            try
            {
                w.Close();
            }
            catch
            {

            }
            
        }

        private static void WriteAliases(XmlTextWriter w, Alias a)
        {
            w.WriteStartElement("Alias");
            w.WriteAttributeString("Alias", a.AliasName);
            w.WriteAttributeString("Path", a.Path);
            w.WriteAttributeString("Parameters", a.Parameters);
            w.WriteAttributeString("Description", a.Description);
            w.WriteEndElement();
        }
    }

}
